(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], factory);
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory();
  } else {
    // Browser globals (root is window)
    root.StringMask = factory();
  }
}(this, function () {
  var tokens = {
    '0': {pattern: /\d/, _default: '0'},
    '9': {pattern: /\d/, optional: true},
    '#': {pattern: /\d/, optional: true, recursive: true},
    'S': {pattern: /[a-zA-Z]/},
    'U': {pattern: /[a-zA-Z]/, transform: function (c) { return c.toLocaleUpperCase(); }},
    'L': {pattern: /[a-zA-Z]/, transform: function (c) { return c.toLocaleLowerCase(); }},
    '$': {escape: true}
  };

  function isEscaped(pattern, pos) {
    var count = 0;
    var i = pos - 1;
    var token = {escape: true};
    while (i >= 0 && token && token.escape) {
      token = tokens[pattern.charAt(i)];
      count += token && token.escape ? 1 : 0;
      i--;
    }
    return count > 0 && count%2 === 1;
  }

  function calcOptionalNumbersToUse(pattern, value) {
    var numbersInP = pattern.replace(/[^0]/g,'').length;
    var numbersInV = value.replace(/[^\d]/g,'').length;
    return numbersInV - numbersInP;
  }

  function concatChar(text, character, options, token) {
    if (token && typeof token.transform === 'function') character = token.transform(character);
    if (options.reverse) return character + text;
    return text + character;
  }

  function hasMoreTokens(pattern, pos, inc) {
    var pc = pattern.charAt(pos);
    var token = tokens[pc];
    if (pc === '') return false;
    return token && !token.escape ? true : hasMoreTokens(pattern, pos + inc, inc);
  }

  function insertChar(text, char, position) {
    var t = text.split('');
    t.splice(position >= 0 ? position: 0, 0, char);
    return t.join('');
  }

  function StringMask(pattern, opt) {
    this.options = opt || {};
    this.options = {
      reverse: this.options.reverse || false,
      usedefaults: this.options.usedefaults || this.options.reverse
    };
    this.pattern = pattern;
  }

  StringMask.prototype.process = function proccess(value) {
    if (!value) {
      return {result: '', valid: false};
    }
    value = value + '';
    var pattern2 = this.pattern;
    var valid = true;
    var formatted = '';
    var valuePos = this.options.reverse ? value.length - 1 : 0;
    var optionalNumbersToUse = calcOptionalNumbersToUse(pattern2, value);
    var escapeNext = false;
    var recursive = [];
    var inRecursiveMode = false;

    var steps = {
      start: this.options.reverse ? pattern2.length - 1 : 0,
      end: this.options.reverse ? -1 : pattern2.length,
      inc: this.options.reverse ? -1 : 1
    };

    function continueCondition(options) {
      if (!inRecursiveMode && hasMoreTokens(pattern2, i, steps.inc)) {
        return true;
      } else if (!inRecursiveMode) {
        inRecursiveMode = recursive.length > 0;
      }

      if (inRecursiveMode) {
        var pc = recursive.shift();
        recursive.push(pc);
        if (options.reverse && valuePos >= 0) {
          i++;
          pattern2 = insertChar(pattern2, pc, i);
          return true;
        } else if (!options.reverse && valuePos < value.length) {
          pattern2 = insertChar(pattern2, pc, i);
          return true;
        }
      }
      return i < pattern2.length && i >= 0;
    }

    for (var i = steps.start; continueCondition(this.options); i = i + steps.inc) {
      var pc = pattern2.charAt(i);
      var vc = value.charAt(valuePos);
      var token = tokens[pc];
      if (!inRecursiveMode || vc) {
        if (this.options.reverse && isEscaped(pattern2, i)) {
          formatted = concatChar(formatted, pc, this.options, token);
          i = i + steps.inc;
          continue;
        } else if (!this.options.reverse && escapeNext) {
          formatted = concatChar(formatted, pc, this.options, token);
          escapeNext = false;
          continue;
        } else if (!this.options.reverse && token && token.escape) {
          escapeNext = true;
          continue;
        }
      }

      if (!inRecursiveMode && token && token.recursive) {
        recursive.push(pc);
      } else if (inRecursiveMode && !vc) {
        if (!token || !token.recursive) formatted = concatChar(formatted, pc, this.options, token);
        continue;
      } else if (recursive.length > 0 && token && !token.recursive) {
        // Recursive tokens most be the last tokens of the pattern
        valid = false;
        continue;
      } else if (!inRecursiveMode && recursive.length > 0 && !vc) {
        continue;
      }

      if (!token) {
        formatted = concatChar(formatted, pc, this.options, token);
        if (!inRecursiveMode && recursive.length) {
          recursive.push(pc);
        }
      } else if (token.optional) {
        if (token.pattern.test(vc) && optionalNumbersToUse) {
          formatted = concatChar(formatted, vc, this.options, token);
          valuePos = valuePos + steps.inc;
          optionalNumbersToUse--;
        } else if (recursive.length > 0 && vc) {
          valid = false;
          break;
        }
      } else if (token.pattern.test(vc)) {
        formatted = concatChar(formatted, vc, this.options, token);
        valuePos = valuePos + steps.inc;
      } else if (!vc && token._default && this.options.usedefaults) {
        formatted = concatChar(formatted, token._default, this.options, token);
      } else {
        valid = false;
        break;
      }
    }

    return {result: formatted, valid: valid};
  };

  StringMask.prototype.apply = function(value) {
    return this.process(value).result;
  };

  StringMask.prototype.validate = function(value) {
    return this.process(value).valid;
  };

  StringMask.process = function(value, pattern, options) {
    return new StringMask(pattern, options).process(value);
  };

  StringMask.apply = function(value, pattern, options) {
    return new StringMask(pattern, options).apply(value);
  };

  StringMask.validate = function(value, pattern, options) {
    return new StringMask(pattern, options).validate(value);
  };

  return StringMask;
}));


(function() {
    'use strict';

    function maxValidator(ctrl, value, limit) {
        var max = parseFloat(limit);
        var validity = ctrl.$isEmpty(value) || isNaN(max)|| value <= max;
        ctrl.$setValidity('max', validity);
        return value;
    }

    function minValidator(ctrl, value, limit) {
        var min = parseFloat(limit);
        var validity = ctrl.$isEmpty(value) || isNaN(min) || value >= min;
        ctrl.$setValidity('min', validity);
        return value;
    }

    var cnpjPattern = new StringMask('00.000.000\/0000-00');
    var cpfPattern = new StringMask('000.000.000-00');

    function numberViewMask (decimals, decimalDelimiter, thousandsDelimiter) {
        var mask = '#' + thousandsDelimiter + '##0';

        if(decimals > 0) {
            mask += decimalDelimiter;
            for (var i = 0; i < decimals; i++) {
                mask += '0';
            }
        }

        return new StringMask(mask, {
            reverse:true
        });
    }

    function numberModelMask (decimals) {
        var mask = '###0';

        if(decimals > 0) {
            mask += '.';
            for (var i = 0; i < decimals; i++) {
                mask += '0';
            }
        }

        return new StringMask(mask, {
            reverse:true
        });
    }

    function clearDelimitersAndLeadingZeros (value) {
        var cleanValue = value.replace(/^0*/, '');
        cleanValue = cleanValue.replace(/[^0-9]/g, '');
        return cleanValue;
    }

    function preparePercentageToFormatter (value, decimals) {
        return clearDelimitersAndLeadingZeros((parseFloat(value)*100).toFixed(decimals));
    }

    function prepareNumberToFormatter (value, decimals) {
        return clearDelimitersAndLeadingZeros((parseFloat(value)).toFixed(decimals));
    }

    function uiBrCpfMask() {
        function applyCpfMask (value) {
            if(!value) {
                return value;
            }
            var formatedValue = cpfPattern.apply(value);
            return formatedValue.trim().replace(/[^0-9]$/, '');
        }

        return {
            restrict: 'A',
            require: '?ngModel',
            link: function (scope, element, attrs, ctrl) {
                if (!ctrl) {
                    return;
                }

                ctrl.$formatters.push(function(value) {
                    return applyCpfMask(value);
                });

                ctrl.$parsers.push(function(value) {
                    if(!value) {
                        return value;
                    }

                    var actualNumber = value.replace(/[^\d]/g,'');
                    var formatedValue = applyCpfMask(actualNumber);
                    ctrl.$setValidity('cpf', BrV.cpf.validate(formatedValue));

                    if (ctrl.$viewValue !== formatedValue) {
                        ctrl.$setViewValue(formatedValue);
                        ctrl.$render();
                    }

                    return formatedValue.replace(/[^\d]+/g,'');
                });
            }
        };
    }

    function uiBrCnpjMask() {
        function applyCnpjMask (value) {
            if(!value) {
                return value;
            }
            var formatedValue = cnpjPattern.apply(value);
            return formatedValue.trim().replace(/[^0-9]$/, '');
        }
        return {
            restrict: 'A',
            require: '?ngModel',
            link: function (scope, element, attrs, ctrl) {
                if (!ctrl) {
                    return;
                }

                ctrl.$formatters.push(function(value) {
                    return applyCnpjMask(value);
                });

                ctrl.$parsers.push(function(value) {
                    if(!value) {
                        return value;
                    }

                    var actualNumber = value.replace(/[^\d]+/g,'');
                    var formatedValue = applyCnpjMask(actualNumber);
                    ctrl.$setValidity('cnpj', BrV.cnpj.validate(formatedValue));

                    if (ctrl.$viewValue !== formatedValue) {
                        ctrl.$setViewValue(formatedValue);
                        ctrl.$render();
                    }

                    return formatedValue.replace(/[^\d]+/g,'');
                });
            }
        };
    }

    function uiBrCpfCnpjMask() {
        function applyCpfCnpjMask (value) {
            if(!value) {
                return value;
            }
            var formatedValue;
            if (value.length > 11) {
                formatedValue = cnpjPattern.apply(value);
            } else {
                formatedValue = cpfPattern.apply(value);
            }
            return formatedValue.trim().replace(/[^0-9]$/, '');
        }
        return {
            restrict: 'A',
            require: '?ngModel',
            link: function (scope, element, attrs, ctrl) {
                if (!ctrl) {
                    return;
                }

                ctrl.$formatters.push(function(value) {
                    return applyCpfCnpjMask(value);
                });

                ctrl.$parsers.push(function(value) {
                    if(!value) {
                        return value;
                    }
                    var actualNumber = value.replace(/[^\d]+/g,'');

                    var formatedValue = applyCpfCnpjMask(actualNumber);
                    if (actualNumber.length > 11) {
                        ctrl.$setValidity('cnpj', BrV.cnpj.validate(formatedValue));
                        ctrl.$setValidity('cpf', true);
                    } else {
                        ctrl.$setValidity('cpf', BrV.cpf.validate(formatedValue));
                        ctrl.$setValidity('cnpj', true);
                    }

                    if (ctrl.$viewValue !== formatedValue) {
                        ctrl.$setViewValue(formatedValue);
                        ctrl.$render();
                    }

                    return formatedValue.replace(/[^\d]+/g,'');
                });
            }
        };
    }

    angular.module('ui.utils.masks', [])
        .directive('uiPercentageMask', ['$locale', function ($locale) {
            var decimalDelimiter = $locale.NUMBER_FORMATS.DECIMAL_SEP,
                thousandsDelimiter = $locale.NUMBER_FORMATS.GROUP_SEP;

            return {
                restrict: 'A',
                require: '?ngModel',
                scope: {
                    min: '=?min',
                    max: '=?max'
                },
                link: function (scope, element, attrs, ctrl) {
                    if (!ctrl) {
                        return;
                    }

                    var decimals = parseInt(attrs.uiPercentageMask);
                    if(isNaN(decimals)) {
                        decimals = 2;
                    }
                    var numberDecimals = decimals + 2;
                    var viewMask = numberViewMask(decimals, decimalDelimiter, thousandsDelimiter),
                        modelMask = numberModelMask(numberDecimals);

                    ctrl.$formatters.push(function(value) {
                        if(!value) {
                            return ' %';
                        }

                        var valueToFormat = preparePercentageToFormatter(value, decimals);
                        return viewMask.apply(valueToFormat) + ' %';
                    });

                    ctrl.$parsers.push(function(value) {
                        function renderValue(formatedValue) {
                            if (ctrl.$viewValue !== formatedValue) {
                                ctrl.$setViewValue(formatedValue);
                                ctrl.$render();
                            }
                        }
                        if(!value) {
                            renderValue(' %');
                            return value;
                        }

                        var valueToFormat = clearDelimitersAndLeadingZeros(value);
                        if(value && value.indexOf('%') < 0 && valueToFormat.length >= 1) {
                            valueToFormat = valueToFormat.substr(0,valueToFormat.length-1);
                        }
                        var formatedValue = ' %';
                        var actualNumber;
                        if (valueToFormat) {
                            formatedValue = viewMask.apply(valueToFormat) + ' %';
                            actualNumber = parseFloat(modelMask.apply(valueToFormat));
                        }
                        renderValue(formatedValue);

                        return actualNumber;
                    });

                    if(attrs.min){
                        ctrl.$parsers.push(function(value) {
                            return minValidator(ctrl, value, scope.min);
                        });

                        scope.$watch('min', function() {
                            minValidator(ctrl, ctrl.$modelValue, scope.min);
                        });
                    }

                    if(attrs.max) {
                        ctrl.$parsers.push(function(value) {
                            return maxValidator(ctrl, value, scope.max);
                        });

                        scope.$watch('max', function() {
                            maxValidator(ctrl, ctrl.$modelValue, scope.max);
                        });
                    }
                }
            };
        }])
        .directive('uiNumberMask', ['$locale', function ($locale) {
            var decimalDelimiter = $locale.NUMBER_FORMATS.DECIMAL_SEP,
                thousandsDelimiter = $locale.NUMBER_FORMATS.GROUP_SEP;

            return {
                restrict: 'A',
                require: '?ngModel',
                scope: {
                    min: '=?min',
                    max: '=?max'
                },
                link: function (scope, element, attrs, ctrl) {
                    if (!ctrl) {
                        return;
                    }

                    var decimals = parseInt(attrs.uiNumberMask);
                    if(isNaN(decimals)) {
                        decimals = 2;
                    }
                    var viewMask = numberViewMask(decimals, decimalDelimiter, thousandsDelimiter),
                        modelMask = numberModelMask(decimals);

                    ctrl.$formatters.push(function(value) {
                        if(!value) {
                            return value;
                        }

                        var valueToFormat = prepareNumberToFormatter(value, decimals);
                        return viewMask.apply(valueToFormat);
                    });

                    ctrl.$parsers.push(function(value) {
                        if(!value) {
                            return value;
                        }

                        var valueToFormat = clearDelimitersAndLeadingZeros(value);
                        var formatedValue = viewMask.apply(valueToFormat);
                        var actualNumber = parseFloat(modelMask.apply(valueToFormat));

                        if(angular.isDefined(attrs.uiNegativeNumber)){
                            var isNegative = (value[0] === '-'),
                                needsToInvertSign = (value.slice(-1) === '-');

                            //only apply the minus sign if is negative or(exclusive) needs to be negative
                            if(needsToInvertSign ^ isNegative) {
                                actualNumber *= -1;
                                formatedValue = '-' + formatedValue;
                            }
                        }

                        if (ctrl.$viewValue !== formatedValue) {
                            ctrl.$setViewValue(formatedValue);
                            ctrl.$render();
                        }

                        return actualNumber;
                    });

                    if(attrs.min){
                        ctrl.$parsers.push(function(value) {
                            return minValidator(ctrl, value, scope.min);
                        });

                        scope.$watch('min', function() {
                            minValidator(ctrl, ctrl.$modelValue, scope.min);
                        });
                    }

                    if(attrs.max) {
                        ctrl.$parsers.push(function(value) {
                            return maxValidator(ctrl, value, scope.max);
                        });

                        scope.$watch('max', function() {
                            maxValidator(ctrl, ctrl.$modelValue, scope.max);
                        });
                    }
                }
            };
        }])
        .directive('uiBrCpfMask', [uiBrCpfMask])
        .directive('uiBrCnpjMask', [uiBrCnpjMask])
        .directive('uiBrCpfcnpjMask', [uiBrCpfCnpjMask])
        // deprecated: will be removed in the next major version
        .directive('uiCpfMask', [uiBrCpfMask])
        // deprecated: will be removed in the next major version
        .directive('uiCnpjMask', [uiBrCnpjMask])
        // deprecated: will be removed in the next major version
        .directive('uiCpfcnpjMask', [uiBrCpfCnpjMask])
        .directive('uiMoneyMask', ['$locale', function ($locale) {
            var decimalDelimiter = $locale.NUMBER_FORMATS.DECIMAL_SEP;
            var thousandsDelimiter = $locale.NUMBER_FORMATS.GROUP_SEP;
            var currencySym = $locale.NUMBER_FORMATS.CURRENCY_SYM;
            return {
                restrict: 'A',
                require: '?ngModel',
                link: function (scope, element, attrs, ctrl) {
                    if (!ctrl) {
                        return;
                    }

                    var decimals = parseInt(attrs.uiMoneyMask);
                    if(isNaN(decimals)) {
                        decimals = 2;
                    }
                    var decimalsPattern = decimals > 0 ? decimalDelimiter + new Array(decimals + 1).join('0') : '';
                    var maskPattern = currencySym+' #'+thousandsDelimiter+'##0'+decimalsPattern;
                    var moneyMask = new StringMask(maskPattern, {reverse: true});

                    ctrl.$formatters.push(function(value) {
                        if(!value) {
                            return value;
                        }

                        return moneyMask.apply(value.toFixed(decimals).replace(/[^\d]+/g,''));
                    });

                    ctrl.$parsers.push(function(value) {
                        if (!value) {
                            return value;
                        }

                        var actualNumber = value.replace(/[^\d]+/g,'');
                        actualNumber = actualNumber.replace(/^[0]+([1-9])/,'$1');
                        var formatedValue = moneyMask.apply(actualNumber);

                        if (value !== formatedValue) {
                            ctrl.$setViewValue(formatedValue);
                            ctrl.$render();
                        }

                        return parseInt(formatedValue.replace(/[^\d]+/g,''))/Math.pow(10,decimals);
                    });
                }
            };
        }])
        .directive('uiBrPhoneNumber',function() {
            /**
             * FIXME: all numbers will have 9 digits after 2016.
             * see http://portal.embratel.com.br/embratel/9-digito/
             */
            var phoneMask8D = new StringMask('(00) 0000-0000'),
                phoneMask9D = new StringMask('(00) 00000-0000');

            function clearValue (value) {
                if(!value) {
                    return value;
                }

                return value.replace(/[^0-9]/g, '');
            }

            function applyPhoneMask (value) {
                if(!value) {
                    return value;
                }

                var formatedValue;
                if(value.length < 11){
                    formatedValue = phoneMask8D.apply(value);
                }else{
                    formatedValue = phoneMask9D.apply(value);
                }

                return formatedValue.trim().replace(/[^0-9]$/, '');
            }

            return {
                restrict: 'A',
                require: '?ngModel',
                link: function(scope, element, attrs, ctrl) {
                    if (!ctrl) {
                        return;
                    }

                    ctrl.$formatters.push(function(value) {
                        return applyPhoneMask(value);
                    });

                    ctrl.$parsers.push(function(value) {
                        if (!value) {
                            return value;
                        }

                        var cleanValue = clearValue(value);
                        var formatedValue = applyPhoneMask(cleanValue);

                        if (ctrl.$viewValue !== formatedValue) {
                            ctrl.$setViewValue(formatedValue);
                            ctrl.$render();
                        }

                        return clearValue(formatedValue);
                    });
                }
            };
        })
        .directive('uiBrCepMask',function() {
            var cepMask = new StringMask('00000-000');

            function clearValue (value) {
                if(!value) {
                    return value;
                }

                return value.replace(/[^0-9]/g, '');
            }

            function applyCepMask (value, ctrl) {
                if(!value) {
                    return value;
                }
                var processed = cepMask.process(value);
                ctrl.$setValidity('cep', processed.valid);
                var formatedValue = processed.result;
                return formatedValue.trim().replace(/[^0-9]$/, '');
            }

            return {
                restrict: 'A',
                require: '?ngModel',
                link: function(scope, element, attrs, ctrl) {
                    if (!ctrl) {
                        return;
                    }

                    ctrl.$formatters.push(function(value) {
                        return applyCepMask(value, ctrl);
                    });

                    ctrl.$parsers.push(function(value) {
                        if (!value) {
                            return value;
                        }

                        var cleanValue = clearValue(value);
                        var formatedValue = applyCepMask(cleanValue, ctrl);

                        if (ctrl.$viewValue !== formatedValue) {
                            ctrl.$setViewValue(formatedValue);
                            ctrl.$render();
                        }

                        return clearValue(formatedValue);
                    });
                }
            };
        })
        .directive('uiBrIeMask',function() {

            var ieMasks = {
                'AC': [{mask: new StringMask('00.000.000/000-00')}],
                'AL': [{mask: new StringMask('000000000')}],
                'AM': [{mask: new StringMask('00.000.000-0')}],
                'AP': [{mask: new StringMask('000000000')}],
                'BA': [{chars: 8, mask: new StringMask('000000-00')},
                    {mask: new StringMask('0000000-00')}],
                'CE': [{mask: new StringMask('00000000-0')}],
                'DF': [{mask: new StringMask('00000000000-00')}],
                'ES': [{mask: new StringMask('00000000-0')}],
                'GO': [{mask: new StringMask('00.000.000-0')}],
                'MA': [{mask: new StringMask('000000000')}],
                'MG': [{mask: new StringMask('000.000.000/0000')}],
                'MS': [{mask: new StringMask('000000000')}],
                'MT': [{mask: new StringMask('0000000000-0')}],
                'PA': [{mask: new StringMask('00-000000-0')}],
                'PB': [{mask: new StringMask('00000000-0')}],
                'PE': [{chars: 9, mask: new StringMask('0000000-00')},
                    {mask: new StringMask('00.0.000.0000000-0')}],
                'PI': [{mask: new StringMask('000000000')}],
                'PR': [{mask: new StringMask('000.00000-00')}],
                'RJ': [{mask: new StringMask('00.000.00-0')}],
                'RN': [{chars: 9, mask: new StringMask('00.000.000-0')},
                    {mask: new StringMask('00.0.000.000-0')}],
                'RO': [{mask: new StringMask('0000000000000-0')}],
                'RR': [{mask: new StringMask('00000000-0')}],
                'RS': [{mask: new StringMask('000/0000000')}],
                'SC': [{mask: new StringMask('000.000.000')}],
                'SE': [{mask: new StringMask('00000000-0')}],
                'SP': [{mask: new StringMask('000.000.000.000')},
                    {mask: new StringMask('-00000000.0/000')}],
                'TO': [{mask: new StringMask('00000000000')}]
            };

            function clearValue (value) {
                if(!value) {
                    return value;
                }
                return value.replace(/[^0-9]/g, '');
            }

            function getMask(uf, value) {
                if(!uf || !ieMasks[uf]) {
                    return undefined;
                }
                var _uf = uf.toUpperCase();
                if (_uf === 'SP' && /^P/i.test(value)) {
                    return ieMasks.SP[1].mask;
                }
                var masks = ieMasks[uf];
                var i = 0;
                while(masks[i].chars && masks[i].chars < clearValue(value).length && i < masks.length - 1) {
                    i++;
                }
                return masks[i].mask;
            }

            function applyIEMask (value, uf, ctrl) {
                var mask = getMask(uf, value);
                if(!value || !mask) {
                    return value;
                }
                var processed = mask.process(clearValue(value));
                ctrl.$setValidity('ie', BrV.ie(uf).validate(value));
                var formatedValue = processed.result;
                if (uf && uf.toUpperCase() === 'SP' && /^p/i.test(value)) {
                    return 'P'+(formatedValue ? formatedValue.trim().replace(/[^0-9]$/, '') : '');
                }
                return formatedValue.trim().replace(/[^0-9]$/, '');
            }

            return {
                restrict: 'A',
                require: '?ngModel',
                scope: {
                    state: '=uiBrIeMask'
                },
                link: function(scope, element, attrs, ctrl) {
                    if (!ctrl) {
                        return;
                    }

                    scope.$watch('state', function(state) {
                        applyIEMask(ctrl.$viewValue, state, ctrl);
                    });

                    ctrl.$formatters.push(function(value) {
                        return applyIEMask(value, scope.state, ctrl);
                    });

                    ctrl.$parsers.push(function(value) {
                        if (!value) {
                            return value;
                        }

                        var formatedValue = applyIEMask(value, scope.state, ctrl);

                        if (ctrl.$viewValue !== formatedValue) {
                            ctrl.$setViewValue(formatedValue);
                            ctrl.$render();
                        }

                        if (scope.state && scope.state.toUpperCase() === 'SP' && /^p/i.test(value)) {
                            return 'P'+clearValue(formatedValue);
                        }
                        return clearValue(formatedValue);
                    });
                }
            };
        });
})();
